import { Directive, ElementRef, Input, OnInit, OnChanges, OnDestroy, SimpleChange, ViewChild } from '@angular/core';
import { debounce, countTransform, flowTransform } from '../utils';
import { text } from '@angular/core/src/render3/instructions';

const $: any = (window as any).$;
const echarts: any = (window as any).echarts;

/**
 * 饼图，该组件在不同的场景下均可使用，应通过配置参数控制该组件处于什么场景
 * dark场景：label的位置:center
 * light场景：label的位置为默认值,
 * 参数结构如下：
 * options: any = {
 *   theme: 'dark',                 // 主题：首页'dark'(default)，其他亮色主题'light'
 *   name:  '',                     // 扇形name属性
 *   formatValue: 'format/flow',    // 1.不设置formatValue时，默认不处理数据
 *                                  // 2.'format': 数据很大时进行加单位('万、亿')处理
 *                                  // 3.'flow':(bps/pps)数据处理('K/M/G/T');
 *   seriesData: {
 *      'DDoS': 200,
 *      '暴力破解': 170,
 *      '蠕虫': 240,
 *      '隐蔽信道': 244,
 *      }
 * };
 */
@Directive({
    selector: '[appEchartsPie]'
})
export class EchartsPieDirective implements OnInit, OnChanges, OnDestroy {
    @Input() appEchartsPie: any; // 图表配置参数
    chart: any; // 图表本身
    resizeNamespace: string = 'resize.' + Date.now(); // 图表绑定到resize事件，需要一个命名空间
    $elem: any;
    constructor(private el: ElementRef) {
        this.$elem = $(el.nativeElement);
    }

    renderChart() {
        const op = {
            tooltip: {
                trigger: 'item',
                formatter: this.appEchartsPie.formatter || '{a} <br/>{b}: {c} ({d}%)',
                backgroundColor: 'rgba(0, 0, 0, 0.7)',
                padding: [15, 20, 15, 20],
                textStyle: {
                    fontSize: '12'
                }
            },
            color: ['#0099FF', '#66CC33', '#00CCCC', '#FFCC33', '#f8c300', '#FF6699', '#68b92e', '#0093dd', '#5dcdf5',
                '#e77817', '#667ab3', '#9866b4', '#36b684', '#da251d', '#68b920', '#3bb3c2', '#56c9a9', '#c55cd5', '#da307c'],
            legend: {
                show: true,
                orient: 'vertical',
                x: 'right',
                y: 'bottom',
                align: 'left',
                textStyle: {
                    color: '#858585',
                    fontSize: 12
                },
                itemGap: 12,
                icon: 'circle',  // 圆形图例
                data: [],
                type: '',
                top: 'middle',
                itemHeight: 10,
                formatter: '' || null,
                tooltip: '' || null
            },
            grid: { top: 60, right: 30, bottom: 24, left: 'auto' },
            series: [{
                name: 'v',
                type: 'pie',
                selectedMode: 'single',
                selectedOffset: 0,
                // roseType: 'radius',
                radius: ['45%', '60%'],
                center: ['23%', '50%'],
                minAngle: 2, // 设置最小角度，避免数量级相差太大时，小数量级的数据在饼图上不能显示出来
                avoidLabelOverlap: true, // 默认关闭防止标签重叠策略,在标签拥挤重叠的情况下会挪动各个标签的位置，防止标签间的重叠
                label: {
                    normal: {
                        show: false,
                        position: 'center'
                    },
                    emphasis: {
                        show: true,
                        textStyle: {
                            fontSize: '18',
                            fontWeight: 'bold',
                            color: '',
                        },
                        formatter: ''
                    }
                },
                itemStyle: {
                    normal: {
                        // shadowBlur: 40,
                        // shadowColor: 'rgba(0, 0, 0, 0.2)',
                    }
                },
                labelLine: {
                    normal: {
                        show: false
                    }
                },
                data: []
            }]
        };

        let optionSeriesData = [];
        const seriesData = [];
        /**
         * dataType === 'array'接受数组形式
         * 解决由于json的key均为数字，导致无法排序的情况
         * 数组形式如：
         * this.appEchartsPie.seriesData = [
         *     [471, 3000], [63374, 2520], [38854, 2520], [2345, 1600], ['其他', 3200]
         * ];
         */
        if (this.appEchartsPie.dataType === 'array') {
            this.appEchartsPie.seriesData.forEach((v, i) => {
                optionSeriesData.push(v[0]);
                seriesData.push({
                    name: v[0],
                    value: v[1],
                });
            });
        } else {
            optionSeriesData = Object.keys(this.appEchartsPie.seriesData)
            optionSeriesData.forEach((v, i) => {
                seriesData.push({
                    name: v,
                    value: this.appEchartsPie.seriesData[v],
                });
            });
        }

        op.series[0].data = seriesData;
        op.series[0].name = this.appEchartsPie.name;
        op.legend.data = optionSeriesData;
        if (this.appEchartsPie.theme === 'light') {
            op.legend.align = 'left';
            op.legend.x = 'right';
            op.legend.y = 'center';

            // 图例超过18个时，不展示图例
            if (op.legend.data.length > 18) {
                op.legend.data = [];
            }

            op.tooltip.textStyle.fontSize = '12';
            op.series[0].avoidLabelOverlap = true;
            op.series[0].name = this.appEchartsPie.name;
            // 注释部分为label样式
            // op.series[0].label.normal.show = true;
            // op.series[0].label.normal.position = 'default';
            // op.series[0].labelLine.normal.show = true;
            op.series[0].center = ['40%', '50%'];
        }

        // 格式化tooltip展示的bps/pps流量数据以及y轴数据
        const transNum = countTransform;
        if (!this.appEchartsPie.formatter) {
            if (this.appEchartsPie.formatValue === 'format') {
                op.tooltip['formatter'] = (val) => {
                    const value: any = transNum(val.value);
                    const html = `<span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:${val.color}"></span>${val.seriesName}<br/>${val.name}:${value} (${val.percent}%)`;
                    return html;
                };
            }
            if (this.appEchartsPie.formatValue === 'flow') {
                op.tooltip['formatter'] = (val) => {
                    const value: any = flowTransform(val.value);
                    const html = `<span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:${val.color}"></span>${val.seriesName}<br/>${val.name}:${value} (${val.percent}%)`;
                    return html;
                };
            }
        }

        if (this.appEchartsPie.formatter) {
            op.tooltip['formatter'] = this.appEchartsPie.formatter;
        }

        if (this.appEchartsPie.radius) {
            op.series[0].radius = this.appEchartsPie.radius;
        }
        if (this.appEchartsPie.center) {
            op.series[0].center = this.appEchartsPie.center;
        }
        if (this.appEchartsPie.legendX) {
            op.legend.x = this.appEchartsPie.legendX;
        }
        if (this.appEchartsPie.legendHidden) {
            op.legend.show = false;
        }
        // if (this.appEchartsPie.formatter) {
        //     op.series[0].label.emphasis.formatter = this.appEchartsPie.formatter;
        // }
        if (this.appEchartsPie.textColor) {
            op.series[0].label.emphasis.textStyle.color = this.appEchartsPie.textColor;
        }
        if (this.appEchartsPie.tooltip === false) {
            delete op.tooltip;
        }
        if (this.appEchartsPie.type) {
            op.legend.type = this.appEchartsPie.type;
        }
        if (this.appEchartsPie.top) {
            op.legend.top = this.appEchartsPie.top;
        }

        if (this.appEchartsPie.pageIcon) {
            Object.keys(this.appEchartsPie.pageIcon).forEach(v => {
                op.legend[v] = this.appEchartsPie.pageIcon[v];
            });
        }

        // 图例标记的高度
        if (this.appEchartsPie.lengendItemHeight !== undefined) {
            op.legend.itemHeight = this.appEchartsPie.lengendItemHeight;
        }

        // 为遮挡图例增添隐藏阈值
        if (this.appEchartsPie.isSpecPie) {
            op.legend['formatter'] = (name) => {
                let len = 0;
                let temp = '';
                for (let i = 0; i < name.length; i++) {
                    if (name.charCodeAt(i) > 127 || name.charCodeAt(i) == 94) {
                        len += 2;
                    } else {
                        len++;
                    }
                    if (len == 11 || len == 12) {
                        temp = name.substr(0, i)
                    }
                    if (len >= 15) {
                        name = temp + '...';
                        break;
                    }
                }
                return name;
            };
            op.legend['tooltip'] = { show: true };
        }

        if (this.appEchartsPie.tooltip && this.appEchartsPie.tooltip.position) {
            op.tooltip['position'] = this.appEchartsPie.tooltip.position;
        }
        this.chart.clear();
        this.chart.setOption(op, false);
    }

    // 初始化画布，绑定resize事件
    initChart() {
        this.chart = echarts.init(this.el.nativeElement);
        const resize = this.chart.resize;
        const resizeNamespace = this.resizeNamespace;
        $(window).off(resizeNamespace);
        $(window).on(resizeNamespace, debounce(resize, 200, false));
        //图上绑定事件
        if (this.appEchartsPie.events) {
            for (const prop in this.appEchartsPie.events) {
                this.chart.on(prop, this.appEchartsPie.events[prop]);
            }
        }
    }

    // 解除resize
    relieve() {
        const resizeNamespace = this.resizeNamespace;
        $(window).off(resizeNamespace);
        if (this.chart) {
            this.chart.dispose();
        }
    }

    ngOnInit() {
    }

    ngOnChanges(changes: {
        [propKey: string]: SimpleChange
    }) {
        const options = changes['appEchartsPie'];
        if (options && options.previousValue !== options.currentValue && options.currentValue) {
            this.relieve();

            this.initChart();
            this.renderChart();
        }
    }

    ngOnDestroy() {
        this.relieve();
    }

    resize(height, width) {
        if (this.chart) {
            this.chart.resize({ width: width, height: height });
        }
    }
}
